//#include <gdk/gdkx.h>
//#include <gdk/gdk.h>

#include <string.h>
#include <pthread.h>
#include <time.h>

#include "minimal.h"


GdkImage *image;
HildonAnimationActor *actor;
GtkWidget *window, *drawing;
GtkWidget* windowG;
#define X_RES           800
#define Y_RES           480
#define D_WIDTH			640
#define D_HEIGHT		480
#define F_WIDTH			800
#define F_HEIGHT		480
		
int screen_size;
unsigned short* screenbuffer = NULL;


unsigned long keys = 0;
pthread_t accel;
int sens,y_def;
bool running;

int keymap[65536];
char *cfile;
char *loadst;
char *file;
bool fullscreen;
void hildon_quit()
{
	gp2x_deinit();
	gtk_main_quit();
	exit(0);
}

static void
window_key_proxy (GtkWidget *widget,
		     GdkEventKey *event,
		     gpointer user_data)
{
	unsigned long key = 0;
switch(keymap[event->hardware_keycode]){
	case -1:
		return; break;
	case 0:
			key = GP2X_LEFT;break;
	case 1:
			key = GP2X_RIGHT;break;
	case 2:
			key = GP2X_UP;break;
	case 3:
			key = GP2X_DOWN;break;
	case 4:
			key = GP2X_B;break;
	case 5:
			key = GP2X_X;break;
	case 6:
			key = GP2X_Y;break;
	case 7:
			key = GP2X_A;break;
	case 8:
			key = GP2X_SELECT;break;
	case 9:
			key = GP2X_START;break;
	case 10:
			key = GP2X_VOL_DOWN;break;
	case 11:
			key = GP2X_VOL_UP;break;
	case 12:
			key = GP2X_L;break;
	case 13:
			key = GP2X_R;break;
	case 14:
		running=false;hildon_quit();break;
	case 15:
			if (event->type == GDK_KEY_PRESS){
			keys |= GP2X_LEFT;
			keys |= GP2X_UP;
			}else if (event->type == GDK_KEY_RELEASE){
			keys &= ~GP2X_LEFT;
			keys &= ~GP2X_UP;
			}
		key = -1;			return ;			break;
	case 16:
			if (event->type == GDK_KEY_PRESS){
			keys |= GP2X_RIGHT;
			keys |= GP2X_UP;
			}else if (event->type == GDK_KEY_RELEASE){
			keys &= ~GP2X_RIGHT;
			keys &= ~GP2X_UP;
			}
		key = -1;			return ;			break;
	case 17:
			if (event->type == GDK_KEY_PRESS){
			keys |= GP2X_LEFT;
			keys |= GP2X_DOWN;
			}else if (event->type == GDK_KEY_RELEASE){
			keys &= ~GP2X_LEFT;
			keys &= ~GP2X_DOWN;
			}
		key = -1;			return ;			break;
	case 18:
			if (event->type == GDK_KEY_PRESS){
			keys |= GP2X_RIGHT;
			keys |= GP2X_DOWN;
			}else if (event->type == GDK_KEY_RELEASE){
			keys &= ~GP2X_RIGHT;
			keys &= ~GP2X_DOWN;
			}
		key = -1;			return ;			break;
	case 19:
		SaveState(cfile);
		key = -1;			return ;			break;
	break;
	case 20:
		LoadState(cfile);
		key = -1;			return ;			break;
	break;
}
	
	if (event->type == GDK_KEY_PRESS) {
		keys |= key;
	}
	else if (event->type == GDK_KEY_RELEASE) {
		keys &= ~key;
	}

}


void hildon_init2(int *argc, char ***argv,char *fl,char* lst,bool fscreen)
{
fullscreen=fscreen;
	file=fl;
	cfile=new char[255];
	sprintf (cfile, "%s.save.%s", file,lst);
	if (Config.PsxOut)printf ("Save file:%s\n",cfile);
	//cfile="/home/opt/psx4m/savestate";
	
	

	// read key config
	FILE* pFile;
	pFile = fopen("/opt/psx4m/keys", "r"); // assume the file exists and has data
	int ch;
	for (int i=0;i<65536;i++)
		keymap[i]=164;
	if (NULL != pFile) {
		for(int i=0;i<21;i++){
			fscanf(pFile, "%i",&ch);
			keymap[ch]=i;
		}
		fclose(pFile);
	}

	
	pFile = fopen("/opt/psx4m/config", "r");
	if (NULL != pFile) {
	fscanf(pFile, "%d %d",&sens,&y_def);
	fclose(pFile);
	}else{
	sens=150;
	y_def=500; //near 45 degrees =)
	}
	
	

	
	gtk_init (argc, argv);
	window = hildon_stackable_window_new ();
	gtk_widget_realize (window);
	gtk_window_fullscreen (GTK_WINDOW(window));
	g_signal_connect (G_OBJECT (window), "key-press-event",		G_CALLBACK (window_key_proxy), NULL);
	g_signal_connect (G_OBJECT (window), "key-release-event",	G_CALLBACK (window_key_proxy), NULL);
	g_signal_connect (G_OBJECT (window), "delete_event",		G_CALLBACK (hildon_quit), NULL);
	gtk_widget_add_events (window, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);

	if (accel_move){
	running = true;
	pthread_create(&accel, NULL, read_accelerometer, NULL );}
	
	actor = HILDON_ANIMATION_ACTOR (hildon_animation_actor_new());
	if (fullscreen){
	hildon_animation_actor_set_position (actor, (X_RES - F_WIDTH)/2, (Y_RES - F_HEIGHT)/2 );
	}else{
	hildon_animation_actor_set_position (actor, (X_RES - D_WIDTH)/2, (Y_RES - D_HEIGHT)/2 );
	
	}
	hildon_animation_actor_set_parent (actor, GTK_WINDOW (window));
#ifndef OPENGL_ESM
	drawing = gtk_image_new ();
	gtk_container_add (GTK_CONTAINER (actor), drawing);
#endif
	gtk_widget_show_all (GTK_WIDGET (actor));
	gdk_window_set_back_pixmap(((GtkWidget*)actor)->window, NULL, FALSE);
    gtk_widget_set_app_paintable((GtkWidget*)actor,TRUE);
	GTK_WIDGET_UNSET_FLAGS (actor, GTK_DOUBLE_BUFFERED);
	gtk_widget_show_all (GTK_WIDGET (window));
	
	windowG=(GtkWidget*)actor;

}

void gp2x_change_res(int w, int h)
{
#ifndef OPENGL_ESM
	if (Config.PsxOut)SysPrintf ("PSX resolution change: %dx%d", w, h);
	
	if (w <= 0 || h <= 0)
		return;
	
	if (image) gdk_image_destroy(image);
	image = gdk_image_new( GDK_IMAGE_FASTEST, gdk_visual_get_system(), w, h );

	screenbuffer = (unsigned short*) image->mem;
	#ifndef PEOPS_GPU
	screen_size = image->bpl * (h / (linesInterlace_user+1)) * image->bpp;
	#else
	screen_size = image->bpl * h * image->bpp;
#endif
	gtk_image_set_from_image (GTK_IMAGE(drawing), image, NULL);

	gtk_window_resize (GTK_WINDOW (actor), w, h);
	
	if (!fullscreen){
	hildon_animation_actor_set_scale (actor,
				(gdouble)D_WIDTH / (gdouble)w,
				(gdouble)D_HEIGHT / (gdouble)h
	);}
	else{
		hildon_animation_actor_set_scale (actor,
				(gdouble)F_WIDTH / (gdouble)w,
				(gdouble)F_HEIGHT / (gdouble)h
	);}
#endif
}

unsigned long gp2x_joystick_read(void)
{
	//printf("gp2x_joystick_read\n");
	/* process GTK+ events */
	while (gtk_events_pending())
		gtk_main_iteration();

	return keys;
}

void gp2x_video_RGB_clearscreen16(void)
{
	#ifndef OPENGL_ESM
	if (gp2x_screen16 && screen_size)
		memset(gp2x_screen16, 0, screen_size);
#endif
}

void updateScreen()
{
	gtk_widget_queue_draw (drawing);
}

void gp2x_printfchar15(gp2x_font *f, unsigned char c)
{
  unsigned short *dst=&((unsigned short*)gp2x_screen16)[f->x+f->y*(image->bpl>>1)],w,h=f->h;
//unsigned char  *src=f->data[ (c%16)*f->w + (c/16)*f->h ];
  unsigned char  *src=&f->data[c*10];

 if(f->solid)
         while(h--)
         {
          w=f->wmask;
          while(w)
          {
           if( *src & w ) *dst++=f->fg; else *dst++=f->bg;
           w>>=1;
          }
          src++;    

          dst+=(image->bpl>>1)-(f->w);
         }
 else
         while(h--)
         {
          w=f->wmask;
          while(w)
          {
           if( *src & w ) *dst=f->fg;
           dst++;
           w>>=1;
          }
          src++;

          dst+=(image->bpl>>1)-(f->w);
         }
}


// original code had copied from picodrive for maemo project
static void *read_accelerometer(void*) {

	while (running){
	int accelstates = 0;
	int x, y, z;
	FILE* f = fopen( "/sys/class/i2c-adapter/i2c-3/3-001d/coord", "r" );
	if( !f ) {printf ("err in accel");continue;}
	fscanf( f, "%d %d %d", &x, &y, &z );
	fclose( f );

	
		
		if( x > sens ) keys |= GP2X_LEFT;
		else if( x < -sens ) keys |= GP2X_RIGHT;
		else {keys &= ~GP2X_LEFT;keys &= ~GP2X_RIGHT;}
		
		y+=y_def;
		if( y > sens )keys |= GP2X_UP;
		else if( y < -sens ) keys |= GP2X_DOWN; 
		else {keys &= ~GP2X_DOWN;keys &= ~GP2X_UP;}
		
		/*if( z > sens ) keys |= GP2X_A;
		else if( z < -sens ) keys |= GP2X_B;
		else {keys &= ~GP2X_A;keys &= ~GP2X_B;}*/
		
usleep (500);
		}
}
